package com.vip.iot.protocol.mina;

import com.vip.common.util.HexBinUtils;
import com.vip.iot.util.PropertiesUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Mina服务端
 *
 * @author wgb
 * @date 2020/6/19 15:31
 */
@Slf4j
@Service
public class MinaServer extends IoHandlerAdapter {
    public static ThreadPoolExecutor threadPool;

    public MinaServer() throws IOException {
        Object minaPort = PropertiesUtils.getYmlFileProperty("application.yml", "mina.port");
        int port = Integer.parseInt(minaPort == null ? "18567" : minaPort.toString());
        NioSocketAcceptor acceptor = new NioSocketAcceptor();
        acceptor.setHandler(this);
        acceptor.bind(new InetSocketAddress(port));
        threadPool = new ThreadPoolExecutor(10, 20, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10)
              , new ThreadPoolExecutor.DiscardOldestPolicy());
        log.info("Mina TCP服务启动，端口：{}", port);
    }

    @Override
    public void messageReceived(IoSession session, Object message) {
        threadPool.execute(() -> {
            IoBuffer bbuf = (IoBuffer) message;
            byte[] byten = new byte[bbuf.limit()];
            bbuf.get(byten, bbuf.position(), bbuf.limit());
            System.out.println("收到消息：" + HexBinUtils.byte2HexStr(byten, byten.length));
            byte[] bts = new byte[10];
            for (int i = 0; i < 10; i++) {
                bts[i] = (byte) i;
            }
            IoBuffer buffer = IoBuffer.allocate(10);
            buffer.put(bts);
            buffer.flip();
            session.write(buffer);
            session.closeNow();
        });

    }

    @Override
    public void sessionClosed(IoSession session) {
    }

    @Override
    public void exceptionCaught(IoSession session, Throwable cause)
          throws Exception {
        super.exceptionCaught(session, cause);
    }

    @Override
    public void messageSent(IoSession iosession, Object obj) throws Exception {
        super.messageSent(iosession, obj);
    }

    @Override
    public void sessionCreated(IoSession iosession) throws Exception {
        super.sessionCreated(iosession);
    }

    @Override
    public void sessionIdle(IoSession iosession, IdleStatus idlestatus)
          throws Exception {
        super.sessionIdle(iosession, idlestatus);
    }

    @Override
    public void sessionOpened(IoSession iosession) throws Exception {
        super.sessionOpened(iosession);
    }
}
